package middleware

import (
	"github.com/gin-gonic/gin"
	"github.com/golang-jwt/jwt/v5"
	"net/http"
	"time"
	ijwt "webook/internal/web/jwt"
)

type LoginJWTMiddlewareBuilder struct {
	ijwt.Handler
}

func NewLoginJWTMiddlewareBuilder(hdl ijwt.Handler) *LoginJWTMiddlewareBuilder {
	return &LoginJWTMiddlewareBuilder{
		hdl,
	}
}

// CheckLogin builder模式
func (m *LoginJWTMiddlewareBuilder) CheckLogin() gin.HandlerFunc {
	return func(ctx *gin.Context) {
		path := ctx.Request.URL.Path
		if path == "/users/signup" || path == "/users/login" ||
			path == "/users/login_sms" || path == "/users/login_sms/code/send" ||
			path == "/oauth2/wechat/authurl" || path == "/oauth2/wechat/callback" {
			return //不需要登录校验
		}
		//根据约定 放在Authorization里 Bearer xxx
		tokenStr := m.ExtractToken(ctx)
		uc := ijwt.UserClaims{}
		token, err := jwt.ParseWithClaims(tokenStr, &uc, func(token *jwt.Token) (interface{}, error) {
			return ijwt.AccessTokenKey, nil
		})
		if err != nil || !token.Valid {
			//err != nil token是伪造的  !token.Valid token非法或过期
			ctx.AbortWithStatus(http.StatusUnauthorized)
			return
		}
		//后期监控告警的时候 这个地方要埋点 能够进来这个分支的 大概率是攻击者
		if ctx.GetHeader("User-Agent") != uc.UserAgent {
			ctx.AbortWithStatus(http.StatusUnauthorized)
			return
		}
		expireTime, err := uc.GetExpirationTime()
		if err != nil {
			// 拿不到过期时间
			ctx.AbortWithStatus(http.StatusUnauthorized)
			return
		}
		if expireTime.Before(time.Now()) {
			// 已经过期
			ctx.AbortWithStatus(http.StatusUnauthorized)
			return
		}
		//if expireTime.Sub(time.Now()) < time.Second*50 {
		//	uc.ExpiresAt = jwt.NewNumericDate(time.Now().Add(time.Minute * 30))
		//	newToken, err := token.SignedString(web.AccessTokenKey)
		//	if err != nil { //刷新这个事情不是必须做的
		//		log.Println(err)
		//	} else {
		//		ctx.Header("x-jwt-token", newToken)
		//	}
		//}

		err = m.CheckSession(ctx, uc.Ssid)
		if err != nil {
			ctx.AbortWithStatus(http.StatusUnauthorized)
			return
		}

		ctx.Set("user", uc)
	}
}
